package com.autumn.chat.socket;

import com.autumn.chat.core.BLiveMessageHandle;
import com.autumn.chat.struct.blive.BLiveProto;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft;
import org.java_websocket.handshake.ServerHandshake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.*;
import java.net.Socket;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Arrays;

public class SSLWebSocketClient extends WebSocketClient {

    private static final Logger log = LoggerFactory.getLogger(SSLWebSocketClient.class);

    /**
     * https://www.sojson.com/blog/353.html
     */
    public SSLWebSocketClient(URI serverURI,Draft draft) {
        super(serverURI,draft);
        if(serverURI.toString().contains("wss://"))
            trustAllHostsNew(this);
    }

    public void sendMsg(String msg) {
        log.info("发送了消息 begin ----- 内容为 : ----->{}",msg );
        this.send(msg.getBytes(StandardCharsets.UTF_8));
    }

    public void sendMsg(byte[] msg) {
        log.info("发送了消息 begin ----- 内容为 : ----->{}",Arrays.toString(msg));
        this.send(msg);
    }

    @Override
    public void onOpen(ServerHandshake serverHandshake) {
        log.info("onOpen -> 成功连接 --------- 展示成功连接的信息 -> \n getHttpStatus - {} || getHttpStatusMessage - {} || getContent - {}",
                serverHandshake.getHttpStatus(),
                serverHandshake.getHttpStatusMessage(),
                Arrays.toString(serverHandshake.getContent()));
    }

    @Override
    public void onMessage(String s) {
        log.info("onMessage -> 收到消息 ---------> {}",s);
    }

    @Override
    public void onMessage(ByteBuffer buffer) {
        // 处理 buffer
        byte[] packet = new byte[buffer.remaining()];
        buffer.get(packet);
        BLiveProto bLiveProto = new BLiveProto(packet);
        // 解包
        bLiveProto.unPack();

        log.info("onMessage -> 收到消息 ---------{}",Arrays.toString(packet));

        // 处理包
        BLiveMessageHandle.OnMessageHandle(bLiveProto);
    }

    @Override
    public void onClose(int i, String s, boolean b) {
        log.info("onClose -> 连接关闭 ---------");
        log.info("code: {} msg: {} b: {}", i, s, b);
    }

    @Override
    public void onError(Exception e) {
        log.error("onError -> 发生错误 ---------",e);
    }

    /**
    * Description: 信任证书
    * @param client
    * @return: void
    * @author: Shen_Yue
    * @Date: 1:50 2023/3/4
    */
    void trustAllHostsNew(SSLWebSocketClient client) {
        TrustManager[] trustAllCerts = new TrustManager[]{new X509ExtendedTrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] x509Certificates, String s, Socket socket) throws CertificateException {

            }

            @Override
            public void checkServerTrusted(X509Certificate[] x509Certificates, String s, Socket socket) throws CertificateException {

            }

            @Override
            public void checkClientTrusted(X509Certificate[] x509Certificates, String s, SSLEngine sslEngine) throws CertificateException {

            }

            @Override
            public void checkServerTrusted(X509Certificate[] x509Certificates, String s, SSLEngine sslEngine) throws CertificateException {

            }

            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }

            @Override
            public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                log.info("checkClientTrusted");
            }

            @Override
            public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                log.info("checkServerTrusted");
            }
        }};
        try {
            SSLContext ssl = SSLContext.getInstance("SSL");
            ssl.init(null, trustAllCerts, new java.security.SecureRandom());
            SSLSocketFactory socketFactory = ssl.getSocketFactory();
            this.setSocketFactory(socketFactory);

        } catch (Exception e) {
            log.error("",e);
        }
    }
}
